package com.gack.business.service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.gack.business.asyncTest.AsyncUser;
import com.gack.business.model.User;
import com.gack.business.model.UserLoginRecord;
import com.gack.business.model.VideoIdentify;
import com.gack.business.repository.UserRepository;
import com.gack.business.repository.VideoIdentifyRepository;
import com.gack.helper.common.abstractobj.ApiController;
import com.gack.helper.common.abstractobj.Result;
import com.gack.helper.common.util.JasyptHelper;
import com.gack.helper.common.util.SystemHelper;
import com.gack.helper.common.util.TokenUtils;
import com.gack.helper.common.util.SendCode;
import com.gack.helper.redis.RedisClient;


/**
 * 
 * @author ws
 * 2018-5-25
 */

@Service
@Transactional
public class UserLoginAndRegisterService implements UserLoginAndRegisterServiceInterface{

	@Autowired
	private VideoIdentifyRepository identifyRepository;
	@Autowired
	private UserRepository userRepository;
	@Autowired
	private RedisClient redisClient;
	@Autowired
	private AsyncUser asyncUser;
	
	/**
	 * 用户注册
	 * @param username 用户名
	 * @param password 密码
	 * @param identifyCode 短信验证码
	 * @param register_source 注册来源 android或ios
	 * @return error:用户名存在    error:验证码超时   error:验证码不正确   success:注册成功
	 */
	@Override
	public Result registUser(String username, String password, String identifyCode, String register_source) {
		Result result = new Result();
		
		//验证短信验证码
		Result validateIdentifyResult = validateIdentify(username, identifyCode);
		if("error".equals(validateIdentifyResult.getKey())){
			return validateIdentifyResult;
		}
		
		//验证用户名,若用户名存在则不允许注册
		List<User> users = userRepository.findByUsername(username);
		if(users != null && users.size() > 0){
			//用户已存在，无法注册
			result.setKey("error");
			result.setValue("该用户已存在，无法重复注册");
			return result;
		}
		
		//用户不存在，则注册
		User user = new User();
		user.setUsername(username);
		//密码加盐加密
		password = JasyptHelper.encrypt(password, ApiController.PASSWORD_SALT);
		user.setPassword(password);
		user.setNickname(username.substring(0, 3)+"****"+username.substring(7));	//设置默认昵称
		user.setPortrait("https://guoanchuangke2.oss-cn-beijing.aliyuncs.com/datas/video/portait/1522745203889.png?Expires=4676344717&OSSAccessKeyId=LTAILWi7cyx4nHeI&Signature=6bsYvd8PTjbilQbWwBfUO1spm6U%3D");
		user.setCreatetime(new Date());
		user.setRegister_source(register_source);
		user.set_check(false);
		user.setIsPledge(0);
		user.setStatus(true);
		userRepository.save(user);
		
		result.setKey("success");
		result.setValue("注册成功");

		return result;
	}
	
	/**
	 * 用户名密码登录
	 * @param username 用户名
	 * @param password 密码
	 * @param login_resource 登录来源   pc或android或ios
	 * @param equipment 设备号
	 * @return error:用户名或密码错误   success:User对象
	 */
	@Override
	public Result loginByPassword(String username, String password, String login_resource, String equipment) {
		Result result = new Result();
		
		//若用户名不存在,则登录失败
		List<User> users = userRepository.findByUsername(username);
		if(users == null || users.size() == 0){
			result.setKey("error");
			result.setValue("用户名或密码错误");
			return result;
		}
		
		User user = users.get(0);
		String uPassword = JasyptHelper.decrypt(user.getPassword(), ApiController.PASSWORD_SALT);		
		if(!password.equals(uPassword)){
			result.setKey("error");
			result.setValue("用户名或密码错误");
			return result;
		}
		
		//若同端登录，则令前一登录的设备号失效;若非同端登录，则保存该设备号。若为PC端登录，则生成token作为唯一标识
		String key;
		if(login_resource.equalsIgnoreCase("android") || login_resource.equalsIgnoreCase("ios")){
			key = username + "mobile";
		}else{
			key = username + "pc";
			equipment = TokenUtils.getUserLoginToken(user.getId());
		}
		redisClient.set(key, equipment);
		
		//记录该用户本次登录时间
		user.setLast_login_time(new Date());
		userRepository.save(user);
		System.out.println("ThreadName1===" + Thread.currentThread().getName());
		//异步添加登录记录
		UserLoginRecord userLoginRecord = new UserLoginRecord();
		userLoginRecord.setUsername(username);
		userLoginRecord.setLogin_time(new Date());
		userLoginRecord.setLogin_resource(login_resource);
		userLoginRecord.setEquipment(equipment);
		asyncUser.saveUserLogin(userLoginRecord);
	
		
		Map<String, Object> map = new HashMap<>();
		map.put("user", user);
		map.put("equipment", equipment);
		result.setKey("success");
		result.setValue(map);
		
		return result;
	}
	
	/**
	 * 用户名短信验证码登录
	 * @param username 用户名
	 * @param identifyCode 短信验证码
	 * @param login_resource 登录来源   pc或android或ios
	 * @param equipment 设备号
	 * @return error:用户名或密码错误   success:User对象
	 */
	@Override
	public Result loginByIdentifyCode(String username, String identifyCode, String login_resource, String equipment) {
		Result result = new Result();
		
		//验证短信验证码
		Result validateIdentifyResult = validateIdentify(username, identifyCode);
		if("error".equals(validateIdentifyResult.getKey())){
			return validateIdentifyResult;
		}
		
		//若用户名不存在,则登录失败
		List<User> users = userRepository.findByUsername(username);
		if(users == null || users.size() == 0){
			result.setKey("error");
			result.setValue("用户名错误");
			return result;
		}
		
		User user = users.get(0);
		//若同端登录，则令前一登录的设备号失效;若非同端登录，则保存该设备号
		String key;
		if(login_resource.equalsIgnoreCase("android") || login_resource.equalsIgnoreCase("ios")){
			key = username + "mobile";
		}else{
			key = username + "pc";
			equipment = TokenUtils.getUserLoginToken(user.getId());
		}
		redisClient.set(key, equipment);
		
		//记录该用户本次登录时间
		user.setLast_login_time(new Date());
		userRepository.save(user);
		//异步添加登录记录
		UserLoginRecord userLoginRecord = new UserLoginRecord();
		userLoginRecord.setUsername(username);
		userLoginRecord.setLogin_time(new Date());
		userLoginRecord.setLogin_resource(login_resource);
		userLoginRecord.setEquipment(equipment);
		asyncUser.saveUserLogin(userLoginRecord);

		
		Map<String, Object> map = new HashMap<>();
		map.put("user", user);
		map.put("equipment", equipment);
		result.setKey("success");
		result.setValue(map);
		
		return result;
	}
	
	/**
	 * 验证短信验证码
	 * @param username 用户名
	 * @param identifyCode 短信验证码
	 * @return
	 */
	@Override
	public Result validateIdentify(String username,String identifyCode){
		Result result = new Result();
		List<VideoIdentify> identifys = identifyRepository.findByUsername(username);
		if(identifys != null && identifys.size() > 0 && identifys.get(0).getIdentifytime() != null){
			VideoIdentify identify = identifys.get(0);
			Date nowDate = new Date();
			long alongTime = 0;	//时间差
			alongTime = nowDate.getTime() - identify.getIdentifytime().getTime();
			if(alongTime > 1000*60*5){
				//登录超时  登录失败
				result.setKey("error");
				result.setValue("验证码超时，请重新获取验证码");
			}else if(!identifyCode.equals(identify.getIdentifycode())){
				//验证码错误
				result.setKey("error");
				result.setValue("验证码错误，请确认验证码");
			}else{
				//验证通过
				result.setKey("success");
				result.setValue("验证码验证通过");
			}
		}else{
			//该用户名不存在验证码信息   验证失败
			result.setKey("error");
			result.setValue("验证失败，请先点击获取短信验证码");
		}
		return result;
	}
	
	/**
	 * 发送短信验证码
	 * @param username 用户名，即手机号
	 * @return
	 */
	@Override
	public Result sendIdentifyCode(String username){
		Result result = new Result();
		
		List<VideoIdentify> identifys = identifyRepository.findByUsername(username);
		VideoIdentify identify = null;
		//用户名已存在  直接修改验证码   不存在  新添加验证信息
		if(identifys != null && identifys.size() > 0){
			identify = identifys.get(0);
		}else{
			identify = new VideoIdentify();
		}
		
		String code = SystemHelper.getSixCode();
		identify.setUsername(username);
		identify.setIdentifycode(code);
		identify.setIdentifytime(new Date());
		String msg = "尊敬的用户您好，您的短信验证码为 "+code+"，有效时间为5分钟，请及时使用";
		try{
			SendCode.sendMessage(username, msg);
			result.setKey("success");
			result.setValue("验证码发送成功");
		}catch (Exception e) {
			e.printStackTrace();
			result.setKey("error");
			result.setKey("验证码发送失败，请再次尝试");
		}
		identifyRepository.save(identify);
		return result;
	}
	
}
